package cc.catface.api.interceptor;

import cc.catface.api.interceptor.readbody.RequestWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.Enumeration;

/**
 * 拦截器-springAOP|反射|可获取IOC容器中的bean以调用业务逻辑如service等
 *
 * 比如可以判断用户是否登录，若未登录直接中断请求处理
 */
@Slf4j
@Component
public class LogInterceptor implements HandlerInterceptor {
    private static final String TAG = LogInterceptor.class.getSimpleName();

    @Override//在controller调用前执行该方法
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        StringBuffer requestURL = request.getRequestURL();//请求url
        StringBuilder sbReqHead = new StringBuilder();
        Enumeration<String> reqHeadNames = request.getHeaderNames();//请求头
        while (reqHeadNames.hasMoreElements()) {
            String reqHeadName = reqHeadNames.nextElement();
            sbReqHead.append(reqHeadName + ":" + request.getHeader(reqHeadName) + ", ");
        }
        String queryString = request.getQueryString();//query参数

        //===>处理请求流只能取一次的问题(获取body入参)<https://blog.csdn.net/qq_16159433/article/details/120922952>
        /*BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8));
        } catch (IOException e) {
            e.printStackTrace();
        }
        String line = null;
        StringBuilder bodyString = new StringBuilder();
        try {
            while ((line = br.readLine()) != null) {
                bodyString.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }*/
        String bodyString = "";
        if (withJson(request)) {
            bodyString = new RequestWrapper(request).getBodyString();
        }//<===

        String sessionID = request.getSession().getId();//请求sessionId
        int status = response.getStatus();//响应码
        StringBuilder sbResHead = new StringBuilder();
        Collection<String> resHeadNames = response.getHeaderNames();//响应头
        resHeadNames.forEach(header -> sbResHead.append(header + ":" + response.getHeader(header) + ", "));
        String hand = handler.toString();//handler
        //打印日志
        log.info("\n{}\n┃请求url=>{}\n┃请求头=>{}\n┃query参数=>{}\n┃body参数=>{}\n┃请求sessionId=>{}\n┃响应码=>{}\n┃响应头=>{}\n┃handler=>{}\n{}",
                "┌-------------------------------------" + TAG,
                requestURL, sbReqHead, queryString, bodyString, sessionID, status, sbResHead, hand,
                "└-------------------------------------");
        return true;
    }

    /*判断本次请求入参是否是json*/
    private boolean withJson(HttpServletRequest request) {
        return true;
        /*if (request.getContentType() != null) {
            return request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE)
                    || request.getContentType().equals(MediaType.APPLICATION_JSON_UTF8_VALUE);
        }
        return false;*/
    }

    /*@Override//controller调用后且在视图渲染前
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("postHandle()");
    }

    @Override//视图渲染后
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("afterCompletion()");
    }*/
}
